﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MindReader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        int userScore = 0,
            computerScore = 0;
        Dictionary<string, Recommendation> dict = new Dictionary<string, Recommendation>();
        const string HEADS = "Heads", TAILS = "Tails";

        public MainWindow()
        {
            InitializeComponent();
            MessageBox.Show("Welcome to Mind Reader.\n\nThe computer will try to guess whether you'll pick heads or tails.\nIf the computer guesses right, he gets a point; otherwise, you do.\n\n First to 25 wins!");
            labelComputerGuess.Content = "";
            labelUserSelection.Content = "";
            labelGameHistory.Content = "";
        }

        private void buttonHeads_Click(object sender, RoutedEventArgs e)
        {
            handleUserInput(HEADS);
        }

        private void buttonTails_Click(object sender, RoutedEventArgs e)
        {
            handleUserInput(TAILS);
        }

        private void handleUserInput(string userInput)
        {
            labelUserSelection.Content = userInput;
            string history = (string)labelGameHistory.Content + userInput[0];
            string matcher = null, three = null, two = null, one = null;
            labelGameHistory.Content = history;

            //find recommendation
            if (history.Length >= 4)
            {
                three = history.Substring(history.Length - 4, 3);
                two = history.Substring(history.Length - 3, 2);
                one = history.Substring(history.Length - 2, 1);
                if (dict.Keys.Contains<string>(three))
                    matcher = three;
            }
            if (matcher == null && history.Length >= 3)
            {
                two = history.Substring(history.Length - 3, 2);
                one = history.Substring(history.Length - 2, 1);
                if (dict.Keys.Contains<string>(two))
                    matcher = two;
            }
            if (matcher == null && history.Length >= 2)
            {
                one = history.Substring(history.Length - 2, 1);
                if (dict.Keys.Contains<string>(one))
                    matcher = one;
            }
            if (matcher != null)
                labelComputerGuess.Content = dict[matcher].BestChoice;
            else
                labelComputerGuess.Content = new Random().Next(2) == 0 ? HEADS : TAILS;


            //determine winner
            if (userInput.Equals(labelComputerGuess.Content.ToString()))
            {
                labelScored.Content = "Computer Scored!";
                labelComputerScore.Content = ++computerScore;
                if (computerScore >= 25)
                {
                    MessageBox.Show("Computer Wins!");
                    gameOver();
                }
            }
            else
            {
                labelScored.Content = "You Scored!";
                labelUserScore.Content = ++userScore; 
                if (userScore >= 25)
                {
                    MessageBox.Show("You Win!");
                    gameOver();
                }
            }


            //record behavior in history
            if (history.Length > 1)
            {
                if (!dict.Keys.Contains<string>(one))
                    dict.Add(one, new Recommendation());

                if (userInput.Equals(HEADS))
                    dict[one].Heads++;
                else
                    dict[one].Tails++;
            }
            if (history.Length > 2)
            {
                if (!dict.Keys.Contains<string>(two))
                    dict.Add(two, new Recommendation());

                if (userInput.Equals(HEADS))
                    dict[two].Heads++;
                else
                    dict[two].Tails++;
            }
            if (history.Length > 3)
            {
                if (!dict.Keys.Contains<string>(three))
                    dict.Add(three, new Recommendation());

                if (userInput.Equals(HEADS))
                    dict[three].Heads++;
                else
                    dict[three].Tails++;
            }
        }

        private void gameOver()
        {
            StringBuilder sb = new StringBuilder("Please copy paste the following into the facebook comment\n(Just push Ctrl+c. It'll work even if the text isn't highlighted)\n\n");
            sb.Append(String.Format("Computer: {0} User: {1}\n", computerScore, userScore));
            var query = from keyvalue in dict
                        orderby keyvalue.Key.Length
                        select keyvalue.Key + " = " + keyvalue.Value.ToString() + "\n";
            foreach(String s in query)
                sb.Append(s);
            MessageBox.Show(sb.ToString());

            if (MessageBox.Show("Play Again?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                computerScore = userScore = 0;
                labelComputerScore.Content = computerScore;
                labelUserScore.Content = userScore;
                labelComputerGuess.Content = "";
                labelUserSelection.Content = "";
                labelGameHistory.Content = "";
                labelScored.Content = "";
                dict.Clear();
            }
            else
            {
                Application.Current.Shutdown();
            }
        }
    }


    public class Recommendation
    {
        int heads, tails;
        static Random random = new Random();
        const string HEADS = "Heads", TAILS = "Tails";

        public int Heads
        {
            get
            {
                return heads;
            }//get
            set
            {
                heads = value;
            }//set
        }//Heads Property

        public int Tails
        {
            get
            {
                return tails;
            }//get
            set
            {
                tails = value;
            }//set
        }//Tails property

        public string BestChoice
        {
            get
            {
                if (heads > tails)
                {
                    return HEADS;
                }//if
                else if (heads < tails)
                {
                    return TAILS;
                }//if
                else
                {
                    return random.Next(2) == 0 ? HEADS : TAILS;
                }//else
            }//get
        }//BestChoice property

        public override string ToString()
        {
            return String.Format("H: {0} T: {1}", heads, tails);
        }
    }//class Recommendation
}//namespace MindReader
